#ifndef ____TCPSERVER_HPP____
#define ____TCPSERVER_HPP____

#include <iostream>
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include "Addr.hpp"
#include <stdio.h>
#include <unistd.h>
#include <string>
#include "Logger.hpp"
#include <sys/wait.h>
#include <pthread.h>

static const int _backlog = 8;

class TcpServer
{
private:
    struct Data
    {
        Data(int sockfd,Inet_Addr Client)
            :_sockfd(sockfd),_Client(Client)
        {}

        ~Data()
        {
           
        }

        int _sockfd;
        Inet_Addr  _Client;
    };

private:
    static void *Routine(void *args)
    {
        pthread_detach(pthread_self());
        struct Data* _ptr = static_cast<struct Data*>(args);
        while (1)
        {
            char buffer[1024] = {0};
            ssize_t n = read(_ptr->_sockfd, buffer, sizeof(buffer) - 1);
            if (n > 0)
            {
                buffer[n] = 0;
                std::cout << "Client Say : " << buffer << std::endl;

                ssize_t ret = write(_ptr->_sockfd, buffer, n);
            }
            else if(n == 0)
            {
                std::cout << "对端关闭" << std::endl;
                break;
            }
        }
        close(_ptr->_sockfd);

        return nullptr;
    }

public:
    TcpServer(uint16_t port)
        : _port(port)
    {
    }

    void Init()
    {
        _listenSockfd = socket(AF_INET, SOCK_STREAM, 0);
        Inet_Addr _addr(_port);
        int n = bind(_listenSockfd, _addr.Addr(), _addr.Size());
        if (n < 0)
        {
            perror("bind");
            return;
        }
        int ret = listen(_listenSockfd, _backlog);
        if (ret < 0)
        {
            perror("listen");
            exit(1);
        }
    }

    void Start()
    {
        while (1)
        {
            struct sockaddr_in _addr;
            memset(&_addr, 0, sizeof(_addr));
            socklen_t _len = sizeof(_addr);

            int _sockfd = accept(_listenSockfd, (struct sockaddr *)&_addr, &_len); // _sockfd == 4
            if (_sockfd < 0)
            {
                continue;
            }

            Inet_Addr _Client(_addr);

            // pid_t _id = fork();
            // if (_id < 0)
            // {
            //     LOG(LogLevel::FATAL) << "fork unsuccess" << "\r\n";
            // }
            // else if (_id == 0)
            // {
            //     close(_listenSockfd);
            //     if (fork() > 0)
            //         exit(0);
            //     Routine(_sockfd, _Client);
            //     exit(0);
            // }
            // close(_sockfd);
            // pid_t _waitid = waitpid(_id, nullptr, 0);

            pthread_t _tid1;
            struct Data _data = {_sockfd,_Client};
            pthread_create(&_tid1, nullptr, Routine,(void*)&_data);
        }
    }

    ~TcpServer()
    {
    }

private:
    int _listenSockfd;
    uint16_t _port;
};

#endif